#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "../inc/wrapper.hpp"

Wrapper::Wrapper(char* workingDir, char* outDir) {
    this->workingDir = workingDir;
    this->outDir = outDir;
}

void Wrapper::setJ2CDir(char* dir) {
    this->j2cDir = dir;
}
extern "C" {

    static int file_filter(const dirent *filename) {
        const char *extension;
        extension = strrchr(filename->d_name, '.');


        if (extension == NULL) {
            return 0;
        }

        extension++;

        /* return only known asset types */
        if (strncasecmp(extension, "j2c", 3) != 0 &&
                strncasecmp(extension, "j2k", 3) != 0 &&
                strncasecmp(extension, "wav", 3) != 0) {
            return 0;
        }

        return 1;
    }
}

int Wrapper::getFileList(context_t* context, char* in_path, filelist_t* filelist) {
    struct dirent **files;
    struct stat st_in;
    struct stat st_out;
    int x = 0;

    if (stat(in_path, &st_in) != 0) {
        printf("Could not open input file %s", in_path);
        return -1;
    }

    if (S_ISDIR(st_in.st_mode)) {
        /* if input is directory, it is jpeg2000 or pcm */
        filelist->count = scandir(in_path, &files, file_filter, alphasort);
        filelist->files = (char**) malloc(filelist->count * sizeof (char*));
        if (filelist->count) {
            for (x = 0; x < filelist->count; x++) {
                filelist->files[x] = (char *) malloc(MAX_FILENAME_LENGTH);
                sprintf(filelist->files[x], "%s/%s", in_path, files[x]->d_name);
            }
        }
        free(files);
    } else {
        /* mpeg2 or time_text */
        int essence_type = get_file_essence_type(in_path);
        if (essence_type == AET_UNKNOWN) {
            return ENCTOOLS_ERROR;
        }
        filelist->count = 1;
        filelist->files = (char**) malloc(filelist->count * sizeof (char*));
        filelist->files[0] = (char *) malloc(MAX_FILENAME_LENGTH);
        filelist->files[0] = in_path;
    }

    return ENCTOOLS_SUCCESS;
}

int Wrapper::wrap() {
    context_t *context = NULL;
    filelist_t *filelist = NULL;
    char out_file[4096];

    context = (context_t *) malloc(sizeof (context_t));
    memset(context, 0, sizeof (context_t));

    filelist = (filelist_t *) malloc(sizeof (filelist_t));
    memset(filelist, 0, sizeof (filelist_t));

    context->xyz = 1;
    context->log_level = LOG_WARN;
    context->ns = XML_NS_SMPTE;
    context->frame_rate = 24;
    context->threads = 4;
    context->ns = XML_NS_SMPTE; //context->ns = XML_NS_INTEROP;


    this->getFileList(context, this->workingDir, filelist);
    if (filelist->count < 1) {
        printf("No input files located");
        exit(1);
    }

    char* videofile = (char*) malloc(100 * sizeof (char));
    sprintf(videofile, "%s/video.mxf", this->outDir);
    if (write_mxf(context, filelist, videofile) != 0) {
        printf("Error!\n");
    }
    
    free(videofile);

    if (context != NULL) {
        free(context);
    }

    for (int j = 0; j < filelist->count; j++) {
        free(filelist->files[j]);
    }
    free(filelist->files);
    free(filelist);


    if (context->log_level > 0) {
        printf("\n");
    }
    return 0;
}

Wrapper::~Wrapper() {

}